package cn.wen.java.utils;

import java.lang.reflect.Array;

import cn.wen.java.lang.HelperOfObject;

/**
 * Title：数组工具类
 * <p>
 * Description：
 * <p>
 * Copyright：Copyright (c) 2010-2012
 * 
 * @author <a href="mailto:ct_wen@qq.com">ctwen</a>, 温承瑭
 * @version Revision：1.0 Date：2011/2/12 Description：初完成。
 *          <p>
 *          Revision：1.1 Date：2011/2/24 Description：新增isEmptyToAll。
 *          <p>
 * @see org.apache.commons.lang.ArrayUtils
 */
public abstract class HelperOfArray {

    /**
     * The index value when an element is not found in a list or array: <code>-1</code>. This value is returned by methods in
     * this class and can also be used in comparisons with values returned by various method from {@link java.util.List}.
     */
    public static final int INDEX_NOT_FOUND = -1;

    /**
     * Determine whether the given object is an array: either an Object array or a primitive array.
     * 
     * @param obj the object to check
     */
    public static boolean isArray(Object obj) {
	return (obj != null && obj.getClass().isArray());
    }

    /**
     * Determine whether the given array is empty: i.e. <code>null</code> or of zero length.
     * 
     * @param array the array to check
     */
    public static boolean isEmpty(Object[] array) {
	return (array == null || array.length == 0);
    }

    /**
     * Determine whether the given array is empty: i.e. <code>null</code> or of zero length, and all element is empty.
     * 
     * @param array the array to check
     */
    public static boolean isEmptyToAll(Object[] array) {
	if (isEmpty(array)) {
	    return true;
	}
	for (Object obj : array) {
	    if (obj != null) {
		return false;
	    }
	}
	return true;
    }

    /**
     * Check whether the given array contains the given element.
     * 
     * @param array the array to check (may be <code>null</code>, in which case the return value will always be
     *            <code>false</code>)
     * @param element the element to check for
     * @return whether the element has been found in the given array
     */
    public static boolean contains(Object[] array, Object element) {
	if (array == null) {
	    return false;
	}
	for (Object arrayEle : array) {
	    if (HelperOfObject.equals(arrayEle, element)) {
		return true;
	    }
	}
	return false;
    }

    /**
     * Convert the given array (which may be a primitive array) to an object array (if necessary of primitive wrapper objects).
     * <p>
     * A <code>null</code> source value will be converted to an empty Object array.
     * 
     * @param source the (potentially primitive) array
     * @return the corresponding object array (never <code>null</code>)
     * @throws IllegalArgumentException if the parameter is not an array
     */
    public static Object[] toObjectArray(Object source) {
	if (source instanceof Object[]) {
	    return (Object[]) source;
	}
	if (source == null) {
	    return new Object[0];
	}
	if (!source.getClass().isArray()) {
	    throw new IllegalArgumentException("Source is not an array: " + source);
	}
	int length = Array.getLength(source);
	if (length == 0) {
	    return new Object[0];
	}
	Class<?> wrapperType = Array.get(source, 0).getClass();
	Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
	for (int i = 0; i < length; i++) {
	    newArray[i] = Array.get(source, i);
	}
	return newArray;
    }

    /**
     * <p>
     * Gets the <code>toString</code> of an <code>Array</code> returning an empty string ("") if <code>null</code> input.
     * </p>
     * 
     * <pre>
     * HelperOfArray.toString("a", new Object[]{"a", "c"}, "c", new Object[]{"a", "c"})) 
     * console: Array:[a, Array:[a, c], c, Array:[a, c]]
     * </pre>
     * 
     * @param objects the Object to <code>toString</code>, may be null
     * @return the passed in Object's toString, or nullStr if <code>null</code> input
     */
    public static String toString(Object[] objects) {
	String mesg = "Array:{";
	for (Object object : objects) {
	    if (HelperOfArray.isArray(object)) {
		mesg += toString(HelperOfArray.toObjectArray(object));
	    }
	    else {
		mesg += object;
	    }
	    mesg += ", ";
	}
	return mesg.substring(0, mesg.length() - 2) + "}";
    }

}
